// @ts-ignore
import { GLTF } from "./gltfInterface";
export default class GltfParser {
  private gltf: GLTF;

  /**
   *
   */
  constructor(gltf: GLTF) {
    this.gltf = gltf;
  }
  // 获取顶点数据
  public getVertices(meshIndex: number = 0): number[] {
    const vertices: number[] = [];
    const mesh = this.gltf.meshes![meshIndex];
    const primitive = mesh.primitives[0];

    // 解析 POSITION 顶点数据
    const positionAccessorIndex = primitive.attributes.POSITION;
    const positionAccessor = this.gltf.accessors![positionAccessorIndex];
    const positionBufferView = this.gltf.bufferViews![positionAccessor.bufferView];
    const buffer = this.gltf.buffers![positionBufferView.buffer];
    const arrayBuffer = this.decodeBase64(buffer.uri!);

    // 使用 DataView 来读取二进制数据
    const dataView = new DataView(arrayBuffer, positionBufferView.byteOffset! + positionAccessor.byteOffset!, positionBufferView.byteLength);
    const componentTypeSize = this.getComponentSize(positionAccessor.componentType);

    // 读取顶点数据，每个顶点有3个 float（x, y, z）
    for (let i = 0; i < positionAccessor.count; i++) {
      const x = dataView.getFloat32(i * componentTypeSize * 3, true);
      const y = dataView.getFloat32(i * componentTypeSize * 3 + 4, true);
      const z = dataView.getFloat32(i * componentTypeSize * 3 + 8, true);
      vertices.push(x, y, z);
    }

    return vertices;
  }

  // 获取索引数据
  public getIndices(meshIndex: number = 0): number[] {
    const indices: number[] = [];
    const mesh = this.gltf.meshes[meshIndex];
    const primitive = mesh.primitives[0];

    // 检查是否有 indices
    if (primitive.indices !== undefined) {
      const indexAccessor = this.gltf.accessors[primitive.indices];
      const indexBufferView = this.gltf.bufferViews[indexAccessor.bufferView];
      const buffer = this.gltf.buffers[indexBufferView.buffer];
      const arrayBuffer = this.decodeBase64(buffer.uri);

      // 根据索引类型（Uint16 或 Uint32）读取数据
      const dataView = new DataView(arrayBuffer, indexBufferView.byteOffset + indexAccessor.byteOffset, indexBufferView.byteLength);
      const componentTypeSize = this.getComponentSize(indexAccessor.componentType);

      for (let i = 0; i < indexAccessor.count; i++) {
        let index;
        if (indexAccessor.componentType === 5123) { // GL_UNSIGNED_SHORT
          index = dataView.getUint16(i * componentTypeSize, true);
        } else if (indexAccessor.componentType === 5125) { // GL_UNSIGNED_INT
          index = dataView.getUint32(i * componentTypeSize, true);
        }
        indices.push(index);
      }
    }

    return indices;
  }

  // 获取单个数据类型的大小
  private getComponentSize(componentType: number): number {
    switch (componentType) {
      case 5120: // BYTE
      case 5121: // UNSIGNED_BYTE
        return 1;
      case 5122: // SHORT
      case 5123: // UNSIGNED_SHORT
        return 2;
      case 5125: // UNSIGNED_INT
      case 5126: // FLOAT
        return 4;
      default:
        throw new Error("Unknown component type.");
    }
  }

  // Base64 解码函数，用于处理 buffer 中的 base64 数据
  private decodeBase64(base64: string): ArrayBuffer {
    const binaryString = atob(base64.split(",")[1]); // 去掉 URI schema 部分
    const len = binaryString.length;
    const bytes = new Uint8Array(len);
    for (let i = 0; i < len; i++) {
      bytes[i] = binaryString.charCodeAt(i);
    }
    return bytes.buffer;
  }
}
